/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.util;

import com.jphenix.clazz.ClassFile;
import com.jphenix.kernel.baseobject.instanceb.ABase;
import com.jphenix.kernel.objectloader.vo.BeanVO;
import com.jphenix.share.lang.*;
import com.jphenix.standard.beans.IFilesUtil;
import com.jphenix.standard.docs.*;
import com.jphenix.standard.lang.ICloneable;

import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;

/**
 * 类处理工具
 * 
 * 2018-08-06 增加了纯java类脚本托管父类功能，即框架调用父类中定义的_executeX方法，可由父类调用其子类脚本中执行入口_execute方法
 * 2019-01-16 在脚本类中，增加了扩展类路径声明，在这里同步修改了解析这个信息的方法
 * 2019-04-09 用SDouble替代了SFloat
 * 2019-07-20 简化了代码，去掉了无用方法
 * 2024-06-05 取消扩展库功能，改用：在WEB-INF/lib中创建子文件夹将jar包归类
 * 2024-06-05 改用SFilesUtil静态文件类
 * 2024-08-16 新增方法 exists(className) 判断指定类是否存在
 * 
 * @author 刘虻
 * 2007-3-13下午12:39:14
 */
@ClassInfo({"2024-08-16 12:48","类处理工具"})
public class ClassUtil {

    /**
     * 构造函数
     * 2007-3-13下午12:39:14
     */
    public ClassUtil() {
        super();
    }
    
    /**
     * 根据类文件路径获取类路径
     * @author 刘虻
     * 2008-4-8下午07:39:29
     * @param filePath      类文件路径
     * @param classBasePath 类根路径，如果filePath为绝对路径，那么该值为空
     * @return 类路径
     */
    public static String getClassPathByFilePath(String filePath,String classBasePath) {
        if (filePath==null) {
            return "";
        }
        //构建类文件
        if (!SFilesUtil.isFileExist(filePath,classBasePath)) {
            return "";
        }
        try {
            return (new ClassFile(filePath)).getName();
        }catch(Exception e) {}
        return "";
    }

    /**
     * 通过类路径获取指定类的父类主键，不存在时返回空字符串
     * 刘虻
     * 2012-12-11 下午2:57:37
     * @param cls 指定类
     * @return 指定父类主键，不存在时返回空字符串
     */
    public static String getParentBeanIDByClass(Class<?> cls) {
        if(cls==null) {
            return "";
        }
        Field field = null; //变量对象
        //先判断该类是不是父类（不单独在类加载器中进行管理的类）
        try {
            field = cls.getDeclaredField("PARENT_BEAN");
        }catch(Exception e) {}
        if(field!=null) {
            field.setAccessible(true);
            try {
                if(SBoolean.valueOf(field.get(null))) {
                    //该类被标记为父类，不在类加载器中进行管理
                    return null;
                }
            }catch(Exception e) {}
            field = null;
        }
        while(field==null && cls!=null && cls!=Object.class) {
            try {
                field = cls.getDeclaredField("PARENT_BEAN_ID");
            }catch(Exception e) {}
            cls = cls.getSuperclass();
        }
        if(field==null) {
            return "";
        }
        field.setAccessible(true);
        try {
            return SString.valueOf(field.get(null));
        }catch(Exception e) {}
        return "";
    }
    
    /**
     * 获取类中定义的类信息常量
     * 
     * 为了不过多的影响加载性能，只取当前类的父类，和当前类的直接接口
     * 
     * 取值的优先级：当前类 --> 父类 --> 当前类的接口
     * 
     * 刘虻
     * 2013-1-7 上午9:56:04
     * @param cls 指定类
     * @return 类信息容器
     */
    public static void getBeanInfoByClass(BeanVO bVO) {
        if(bVO.beanClass==null || bVO.beanClass.isAnonymousClass() || bVO.beanClass.isInterface()) {
            //匿名类、接口，都不能被类加载器管理
            bVO.error = true;
            return;
        }
        /*
         * 从当前类取值
         */
        //类信息
        String[] values = getClassInfo(bVO.beanClass);
        bVO.beanVer = values[0];
        bVO.classTitle = values[1];
        
        values = getBeanInfo(bVO.beanClass);
        bVO.id = values[0];                                                      //类主键
        bVO.isParent = "1".equals(values[1]);                                      //是否为父类
        bVO.parentID = values[2];                             //父类主键
        
        values = getBeanRunning(bVO.beanClass);
        String beanSingleton = values[0]; //是否驻留内存
        bVO.singletonLevel = SInteger.valueOf(beanSingleton);                            //是否常驻内存
        
        bVO.afterStartMethodName = values[1];     //启动后指定的方法名
        bVO.initMethodName = values[2];                              //初始化方法名
        bVO.destoryMethodName = values[3];                //终止类前调用的方法名
        
        bVO.beanRegister = getBeanRegisterID(bVO.beanClass);                         //注册类主键
        if(bVO.isParent) {
            //该类为父类，后面的属性都是关于实体类的，所以不必加载
            return;
        }
        
        /*
         * 从父类中获取
         */
        boolean untrusteeship = true;       //该类是否不托管到类加载器中
        Class<?> pCls =  bVO.beanClass.getSuperclass(); //当前类的父类
        while(pCls!=null && pCls!=Object.class) {
            values = getBeanInfo(pCls);
            if(bVO.parentID.length()<1) {   //父类配置信息主键
                bVO.parentID = values[2];   
            }
            values = getBeanRunning(pCls);
            if(beanSingleton.length()<1) {  //是否驻留内存
                bVO.singletonLevel = SInteger.valueOf(values[0]);
            }
            if(bVO.afterStartMethodName.length()<1) {   //在类加载器加载完毕后执行的方法
                bVO.afterStartMethodName = values[1];   
            }
            if(bVO.initMethodName.length()<1) { //初始化方法
                bVO.initMethodName = values[2];    
            }
            if(bVO.destoryMethodName.length()<1) {  //终止类加载器之前调用的方法
                bVO.destoryMethodName = values[3];  
            }
            if(bVO.beanRegister.length()<1) { //注册类主键
                bVO.beanRegister = getBeanRegisterID(pCls);  
            }
            if(pCls==ABase.class) {
                untrusteeship = false;
                break;
            }
            pCls =  pCls.getSuperclass(); //父类的父类
        }
        if(untrusteeship) {
            //不受类加载器管理
            bVO.error = true;
            return;
        }
        
        /*
         * 从当前类的接口中获取
         */
        //当前类实现的接口
        Class<?>[] iClz = bVO.beanClass.getInterfaces();
        if(iClz!=null) {
            for(int i=0;i<iClz.length;i++) {
                if(bVO.id.length()<1) {
                    values = getBeanInfo(iClz[i]);
                    bVO.id = values[0]; 
                }
                if(bVO.beanRegister.length()<1) {
                    bVO.beanRegister = getBeanRegisterID(iClz[i]);    
                }
            }
        }
    }
    
    /**
     * 获取类文件路径
     * @author 刘虻
     * 2008-4-6上午10:23:08
     * @param classPath 类路径
     * @param classLoader 类加载器
     * @return 类路径URL
     */
    public static URL getClassFilePath(String classPath) {
        URL reUrl = null; //构建返回值
        Class<?> cls = null; //指定类
        try {
            cls = Class.forName(classPath);
        }catch(Exception e) {
            return reUrl;
        }
        if (cls.getClass().getProtectionDomain()!=null 
                && cls.getClass().getProtectionDomain().getCodeSource()!=null) {
            reUrl = cls.getClass().getProtectionDomain().getCodeSource().getLocation();
        }
        if (reUrl==null) {
            //获取类相对路径
            String clsAsResource = cls.getName().replace('.', '/').concat(".class");
            if (cls.getClassLoader()==null) {
                reUrl = cls.getClassLoader().getResource(clsAsResource);
            }else {
                reUrl = ClassLoader.getSystemResource(clsAsResource);
            }
        }
        return reUrl;
    }
    
    
    /**
     * 获取该类所在的路径
     * 刘虻
     * 2010-4-13 上午11:28:10
     * @param cls 指定类
     * @return 该类所在的路径
     */
    public static URL getClassFilePath(Class<?> cls) {
        URL reUrl = null; //构建返回值
        if (cls.getClass().getProtectionDomain()!=null 
                && cls.getClass().getProtectionDomain().getCodeSource()!=null) {
            reUrl = cls.getClass().getProtectionDomain().getCodeSource().getLocation();
        }
        if (reUrl==null) {
            //获取类相对路径
            String clsAsResource = cls.getName().replace('.', '/').concat(".class");
            if (cls.getClassLoader()==null) {
                reUrl = cls.getClassLoader().getResource(clsAsResource);
            }else {
                reUrl = ClassLoader.getSystemResource(clsAsResource);
            }
        }
        return reUrl;
    }
    
    /**
     * 获取类文件路径
     * @author 刘虻
     * 2008-4-6上午10:23:08
     * @param classPath 类路径
     * @param classLoader 类加载器
     * @return 类路径URL
     */
    public static URL getClassFilePath(
            String classPath,ClassLoader classLoader) {
        URL reUrl = null; //构建返回值
        Class<?> cls = null; //指定类
        if (classLoader==null) {
            try {
                cls = Class.forName(classPath);
            }catch(Exception e) {
                //e.printStackTrace();
                //System.err.println("ClassPath:"+System.getProperty("java.class.path"));
                return reUrl;
            }
        }else {
            //URL[] url = null; //报错时输出的类路径信息
            try {
                cls = classLoader.loadClass(classPath);
            }catch(Exception e) {
                //e.printStackTrace();
                //url = ((URLClassLoader)classLoader).getURLs();
                //if (url!=null) {
                //  for (int i=0;i<url.length;i++) {
                //      System.err.println(">>"+url[i]);
                //  }
                //}
                return reUrl;
            }
        }
        if (cls.getClass().getProtectionDomain()!=null 
                && cls.getClass().getProtectionDomain().getCodeSource()!=null) {
            reUrl = cls.getClass().getProtectionDomain().getCodeSource().getLocation();
        }
        if (reUrl==null) {
            //获取类相对路径
            String clsAsResource = cls.getName().replace('.', '/').concat(".class");
            if (cls.getClassLoader()==null) {
                reUrl = cls.getClassLoader().getResource(clsAsResource);
            }else {
                reUrl = ClassLoader.getSystemResource(clsAsResource);
            }
        }
        return reUrl;
    }
    
    
    /**
     * 获取指定类是否为影子类
     * @param cf 类文件对象
     * @return 影子类
     * 2014年6月27日
     * @author 马宝刚
     */
    public static boolean getBeanIsShadow(ClassFile cf) {
		if(cf==null) {
			return false;
		}
		//获取类信息
		Shadow sd = null;
		try {
			 sd = (Shadow)cf.getAnnotationType(Shadow.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getBeanIsShadow(sd);
    }
    
    /**
     * 获取指定类是否为影子类
     * @param cls 指定类
     * @return 影子类
     * 2014年6月27日
     * @author 马宝刚
     */
    public static boolean getBeanIsShadow(Class<?> cls) {
        if(cls==null) {
            return false;
        }
        //获取类信息注释
        return getBeanIsShadow(cls.getAnnotation(Shadow.class));
    }
    
    
    /**
     * 获取指定类是否为影子类
     * @param cls 指定类
     * @return 影子类
     * 2014年6月27日
     * @author 马宝刚
     */
    public static boolean getBeanIsShadow(Shadow cls) {
        if(cls==null) {
            return false;
        }
        //获取注释值数组
        String[] values =  cls.value();
        if(values==null || values.length<1 || values[0]==null) {
            return false;
        }
        return SBoolean.valueOf(values[0]);
    }
    
    /**
     * 获取脚本关联的类主键
     * @param cls 当前脚本类
     * @return 关联的类主键（脚本主键）
     * 2016年3月3日
     * @author 马宝刚
     */
    public static String[] getScriptBuild(Class<?> cls) {
        if(cls==null) {
            return new String[0];
        }
        //获取类信息注释
        ScriptBuild clsInfo = cls.getAnnotation(ScriptBuild.class);
        if(clsInfo==null) {
            return new String[0];
        }
        //获取注释值数组
        String[] values =  clsInfo.value();
        if(values==null) {
            return new String[0];
        }
        return values;
    }
    
    /**
     * 获取脚本关联的类主键，放入序列中
     * @param cls 当前脚本类
     * @param scriptBuildIdList 需要放入的序列
     * 2016年3月3日
     * @author 马宝刚
     */
    public static void getScriptBuild(Class<?> cls,List<String> scriptBuildIdList) {
        if(scriptBuildIdList==null) {
            return;
        }
        String[] values = getScriptBuild(cls);
        for(String ele:values) {
            scriptBuildIdList.add(ele);
        }
    }
    
    /**
     * 获取指定类的类运行时注释信息
     * @param cls 指定类
     * @return
     *                  0: 常驻内存等级  0不常驻内存   1~无穷大    优先级有低到高 <br />
     *                  1: 类加载器全部加载完后，调用的方法<br />
     *                  2:  类加载器加载完当前信息后，调用的方法（此时类加载器并未加载完全部的类）<br />
     *                  3: 类加载器终止前，调用的方法
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanRunning(Class<?> cls) {
        if(cls==null) {
            //构建返回值数组
            String[] reStrs = new String[4];
            reStrs[0] = "0";
            reStrs[1] = "";
            reStrs[2] = "";
            reStrs[3] = "";
            return reStrs;
        }
        //获取类信息注释
        return getBeanRunning(cls.getAnnotation(Running.class));
    }
    
    /**
     * 判断指定类是否为常驻内存类
     * @param obj 指定类实例
     * @return 是否为常驻内存类
     * 2017年3月28日
     * @author MBG
     */
    public static boolean singleton(Class<?> clazz) {
    	if(clazz==null) {
    		return false;
    	}
		try {
			//获取运行时注释信息
			Running cls = clazz.getAnnotation(Running.class);
			if(cls==null) {
				return false;
			}
			//获取注释信息
			String[] infos = cls.value();
            return infos != null && infos.length >= 1 && SInteger.valueOf(infos[0]) >= 1;
        }catch(Exception e) {}
		return false;
    }
    
    /**
     * 判断指定类是否为常驻内存类
     * @param obj 指定类实例
     * @return 是否为常驻内存类
     * 2017年3月28日
     * @author MBG
     */
    public static boolean singleton(Object obj) {
    	if(obj==null) {
    		return false;
    	}
		return singleton(obj.getClass());
    }
    
    /**
     * 获取指定类的类运行时注释信息
     * @param cf 脚本类对象
     * @return
     *                  0: 常驻内存等级  0不常驻内存   1~无穷大    优先级有低到高 <br />
     *                  1: 类加载器全部加载完后，调用的方法<br />
     *                  2:  类加载器加载完当前信息后，调用的方法（此时类加载器并未加载完全部的类）<br />
     *                  3: 类加载器终止前，调用的方法
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanRunning(ClassFile cf) {
		if(cf==null) {
			return new String[0];
		}
		//获取类信息
		Running ri = null;
		try {
			ri = (Running)cf.getAnnotationType(Running.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getBeanRunning(ri);
    }
    
    
    
    /**
     * 获取指定类的类运行时注释信息
     * @param cls Running注释信息类
     * @return
     *                  0: 常驻内存等级  0不常驻内存   1~无穷大    优先级有低到高 <br />
     *                  1: 类加载器全部加载完后，调用的方法<br />
     *                  2:  类加载器加载完当前信息后，调用的方法（此时类加载器并未加载完全部的类）<br />
     *                  3: 类加载器终止前，调用的方法
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanRunning(Running cls) {
        //构建返回值数组
        String[] reStrs = new String[4];
        //获取类信息注释
        if(cls==null) {
            reStrs[0] = "0";
            reStrs[1] = "";
            reStrs[2] = "";
            reStrs[3] = "";
        }else {
            //获取类对应的信息
            String[] value = cls.value();
           if(value==null || value.length<1) {
               reStrs[0] = "0";
               reStrs[1] = "";
               reStrs[2] = "";
               reStrs[3] = "";
           }else if(value.length<2) {
               if(value[0]==null) {
                   reStrs[0] = "0";
               }else {
                   reStrs[0] = SInteger.stringValueOf(value[0]);
               }
               reStrs[1] = "";
               reStrs[2] = "";
               reStrs[3] = "";
           }else if(value.length<3) {
               if(value[0]==null) {
                   reStrs[0] = "0";
               }else {
                   reStrs[0] = SInteger.stringValueOf(value[0]);
               }
               if(value[1]==null) {
                   reStrs[1] = "";
               }else {
                   reStrs[1] = value[1].trim();
               }
               reStrs[2] = "";
               reStrs[3] = "";
           }else if(value.length<4) {
               if(value[0]==null) {
                   reStrs[0] = "0";
               }else {
                   reStrs[0] = SInteger.stringValueOf(value[0]);
               }
               if(value[1]==null) {
                   reStrs[1] = "";
               }else {
                   reStrs[1] = value[1].trim();
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
                   reStrs[2] = value[2].trim();
               }
               reStrs[3] = ""; 
           }else {
               if(value[0]==null) {
                   reStrs[0] = "0";
               }else {
                   reStrs[0] = SInteger.stringValueOf(value[0]);
               }
               if(value[1]==null) {
                   reStrs[1] = "";
               }else {
                   reStrs[1] = value[1].trim();
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
                   reStrs[2] = value[2].trim();
               }
               if(value[3]==null) {
                   reStrs[3] = "";
               }else {
                   reStrs[3] = value[3].trim();
               }
           }
        }
        return reStrs;
    }
    
    /**
     * 获取指定类的注册目标主键
     * @param cls 指定类
     * @return 注册目标主键
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String getBeanRegisterID(Class<?> cls) {
        if(cls==null) {
            return "";
        }
        //获取类信息注释
        return getBeanRegisterID(cls.getAnnotation(Register.class));
    }
    
    /**
     * 获取指定类的注册目标主键
     * @param cf 脚本类对象
     * @return 注册目标主键
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String getBeanRegisterID(ClassFile cf) {
		if(cf==null) {
			return "";
		}
		//获取类信息
		Register rt = null;
		try {
			rt = (Register)cf.getAnnotationType(Register.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getBeanRegisterID(rt);
    }
    
    /**
     * 获取指定类的注册目标主键
     * @param cls Register类
     * @return 注册目标主键
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String getBeanRegisterID(Register cls) {
        if(cls==null) {
            return "";
        }
        //获取注释值数组
        String[] values =  cls.value();
        if(values==null || values.length<1 || values[0]==null) {
            return "";
        }
        return values[0].trim();
    }
    
   
    /**
     * 获取需要加载的类的相关信息
     * @param cls   指定类
     * @return
     *                  0:  类主键<br />
     *                  1:  是否为父类  true是父类  false不是父类<br />
     *                  2:  父类主键，在配置文件中有一段父类配置，在此写入对应的父类主键，可以使用相同的那段配置
     *                  3:  父类介绍，说明父类的作用         
     *                  4：   是否允许在jar内部加载  1允许在jar内部加载                 
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanInfo(Class<?> cls) {
        if(cls==null) {
            //构建返回值数组
            String[] reStrs = new String[5];
            reStrs[0] = "";
            reStrs[1] = "0";
            reStrs[2] = "";
            reStrs[3] = "";
            reStrs[4] = "0";
            return reStrs;
        }
        //获取类信息注释
        return getBeanInfo(cls.getAnnotation(BeanInfo.class));
    }
    
    
    /**
     * 获取需要加载的类的相关信息
     * @param cf   脚本类对象
     * @return
     *                  0:  类主键<br />
     *                  1:  是否为父类  true是父类  false不是父类<br />
     *                  2:  父类主键，在配置文件中有一段父类配置，在此写入对应的父类主键，可以使用相同的那段配置
     *                  3:  父类介绍，说明父类的作用         
     *                  4：   是否允许在jar内部加载  1允许在jar内部加载 
     *                  5：   父类类名（不包含包路径，即不带扩展名的类文件名。因为包路径都是固定的）  
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanInfo(ClassFile cf) {
		if(cf==null) {
			return new String[0];
		}
		//获取类信息
		BeanInfo bi = null;
		try {
			bi = (BeanInfo)cf.getAnnotationType(BeanInfo.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getBeanInfo(bi);
    }
    
    
    /**
     * 获取需要加载的类的相关信息
     * @param cls   BeanInfo类
     * @return
     *                  0:  类主键<br />
     *                  1:  是否为父类  true是父类  false不是父类<br />
     *                  2:  父类主键，在配置文件中有一段父类配置，在此写入对应的父类主键，可以使用相同的那段配置
     *                  3:  父类介绍，说明父类的作用         
     *                  4：   是否允许在jar内部加载  1允许在jar内部加载                 
     *                  
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getBeanInfo(BeanInfo cls) {
        //构建返回值数组
        String[] reStrs = new String[6];
        //获取类信息注释
        if(cls==null) {
            reStrs[0] = "";
            reStrs[1] = "0";
            reStrs[2] = "";
            reStrs[3] = "";
            reStrs[4] = "0";
            reStrs[5] = "";
        }else {
            //获取类对应的信息
            String[] value = cls.value();
           if(value==null || value.length<1) {
               reStrs[0] = "";
               reStrs[1] = "0";
               reStrs[2] = "";
               reStrs[3] = "";
               reStrs[4] = "0";
               reStrs[5] = "";
           }else if(value.length<2) {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               reStrs[1] = "0";
               reStrs[2] = "";
               reStrs[3] = "";
               reStrs[4] = "0";
               reStrs[5] = "";
           }else if(value.length<3) {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "0";
               }else {
                   if(SBoolean.valueOf(value[1])) {
                       reStrs[1] = "1";
                   }else {
                       reStrs[1] = "0";
                   }
               }
               reStrs[2] = "";
               reStrs[3] = "";
               reStrs[4] = "0";
               reStrs[5] = "";
           }else if(value.length<4) {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "0";
               }else {
                   if(SBoolean.valueOf(value[1])) {
                       reStrs[1] = "1";
                   }else {
                       reStrs[1] = "0";
                   }
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
            	   reStrs[2] = value[2].trim();
               }
               reStrs[3] = "";
               reStrs[4] = "0";
               reStrs[5] = "";
           }else if(value.length<5) {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "0";
               }else {
                   if(SBoolean.valueOf(value[1])) {
                       reStrs[1] = "1";
                   }else {
                       reStrs[1] = "0";
                   }
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
            	   reStrs[2] = value[2].trim();
               }
               if(value[3]==null) {
                   reStrs[3] = "";
               }else {
            	   reStrs[3] = value[3].trim();
               }
               reStrs[4] = "0";
               reStrs[5] = "";
           }else if(value.length<6){
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "0";
               }else {
                   if(SBoolean.valueOf(value[1])) {
                       reStrs[1] = "1";
                   }else {
                       reStrs[1] = "0";
                   }
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
                   reStrs[2] = value[2].trim();
               }
               if(value[3]==null) {
                   reStrs[3] = "";
               }else {
                   reStrs[3] = value[3].trim();
               }
               if(value[4]==null) {
                   reStrs[4] = "0";
               }else {
                   if(SBoolean.valueOf(value[4])) {
                       reStrs[4] = "1";
                   }else {
                       reStrs[4] = "0";
                   }
               }
               reStrs[5] = "";
           }else {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "0";
               }else {
                   if(SBoolean.valueOf(value[1])) {
                       reStrs[1] = "1";
                   }else {
                       reStrs[1] = "0";
                   }
               }
               if(value[2]==null) {
                   reStrs[2] = "";
               }else {
                   reStrs[2] = value[2].trim();
               }
               if(value[3]==null) {
                   reStrs[3] = "";
               }else {
                   reStrs[3] = value[3].trim();
               }
               if(value[4]==null) {
                   reStrs[4] = "0";
               }else {
                   if(SBoolean.valueOf(value[4])) {
                       reStrs[4] = "1";
                   }else {
                       reStrs[4] = "0";
                   }
               }
               if(value[5]==null) {
            	   reStrs[5] = "";
               }else {
                   reStrs[5] = value[5].trim();
               }
           }
        }
        return reStrs;
    }
    
    /**
     * 获取脚本注释信息
     * @param cls 指定脚本类
     * @return 注释信息  0脚本类加载器版本
     * 2015年11月25日
     * @author 马宝刚
     */
    public static String[] getScriptInfo(Class<?> cls) {
        if(cls==null) {
        	return null;
        }
        return getScriptInfo(cls.getAnnotation(ScriptInfo.class));
    }
    
    
    /**
     * 获取脚本注释信息
     * @param cf 类文件对象
     * @return 注释信息  0脚本类加载器版本
     * 2015年11月25日
     * @author 马宝刚
     */
    public static String[] getScriptInfo(ClassFile cf) {
		if(cf==null) {
			return null;
		}
		//获取类信息
		ScriptInfo si = null;
		try {
			 si = (ScriptInfo)cf.getAnnotationType(ScriptInfo.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getScriptInfo(si);
    }
    
    
    /**
     * 获取脚本注释信息
     * @param cls 指定脚本类
     * @return 注释信息  0脚本类加载器版本
     * 2015年11月25日
     * @author 马宝刚
     */
    public static String[] getScriptInfo(ScriptInfo cls) {
        //构建返回值数组
        String[] reStrs = null;
        if(cls==null) {
        	return null;
        }else {
           //获取类对应的信息
           String[] values = cls.value();
           if(values==null || values.length<1) {
        	   return null;
           }else {
        	   int length = values.length;
        	   reStrs = new String[length];
               for(int i=0;i<length;i++) {
            	   if(values[i]==null) {
            		   reStrs[i] = "";
            	   }else {
            		   reStrs[i] = values[i];
            	   }
               }
               if(reStrs.length>length) {
            	   fillBlanks(reStrs,reStrs.length-length);
               }
           }
        }
        return reStrs;
    }
    
    
    /**
     * 将数组填充为空字符串
     * @param arr 数组
     * @param fromPoint 从第几个元素开始
     * 2016年11月11日
     * @author MBG
     */
    private static void fillBlanks(String[] arr,int fromPoint) {
    	for(int i=fromPoint;i<arr.length;i++) {
    		arr[i] = "";
    	}
    }
    
    /**
     * 获取类信息
     * @param cls 指定类
     * @return
     *                      0: 版本信息（YYYY-MM-DD HH:mm） 不足位数前面补零<br />
     *                      1: 类文字说明
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getClassInfo(Class<?> cls) {
        if(cls==null) {
            //构建返回值数组
            String[] reStrs = new String[2];
            reStrs[0] = "";
            reStrs[1] = "";
            return reStrs;
        }
        return getClassInfo(cls.getAnnotation(ClassInfo.class));
    }
    
    /**
     * 获取类信息
     * @param cf  脚本类对象
     * @return
     *                      0: 版本信息（YYYY-MM-DD HH:mm） 不足位数前面补零<br />
     *                      1: 类文字说明
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getClassInfo(ClassFile cf) {
		if(cf==null) {
			return new String[0];
		}
		//获取类信息
		ClassInfo ci = null;
		try {
			ci = (ClassInfo)cf.getAnnotationType(ClassInfo.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getClassInfo(ci);
    }
    
    /**
     * 获取指定类的扩展类路径信息
     * 
     * 取消扩展库功能，改用：在WEB-INF/lib中创建子文件夹将jar包归类
     * 
     * @param cf 指定类
     * @return   扩展类路径信息
     * 2019年1月16日
     * @author MBG
     */
    /*
    public static String[] getExtLib(ClassFile cf) {
		if(cf==null) {
			return new String[0];
		}
		//获取类信息
		ExtLib el = null;
		try {
			el = (ExtLib)cf.getAnnotationType(ExtLib.class);
		}catch(Exception e) {
			e.printStackTrace();
		}
		return getExtLib(el);
    }
    */
    
    /**
     * 获取指定类的扩展类路径信息
     * 
     * 取消扩展库功能，改用：在WEB-INF/lib中创建子文件夹将jar包归类
     * 
     * @param cls 扩展类路径信息类
     * @return 扩展类路径信息
     * 2019年1月16日
     * @author MBG
     */
    /*
    public static String[] getExtLib(ExtLib cls) {
        //获取类信息注释
        if(cls==null) {
        	return new String[0];
        }
        return cls.value();
    }
    */
    
    /**
     * 获取类信息
     * @param cls ClassInfo类
     * @return
     *                      0: 版本信息（YYYY-MM-DD HH:mm） 不足位数前面补零<br />
     *                      1: 类文字说明
     * 2014年6月27日
     * @author 马宝刚
     */
    public static String[] getClassInfo(ClassInfo cls) {
        //构建返回值数组
        String[] reStrs = new String[2];
        //获取类信息注释
        if(cls==null) {
            reStrs[0] = "";
            reStrs[1] = "";
        }else {
            //获取类对应的信息
            String[] value = cls.value();
           if(value==null || value.length<1) {
               reStrs[0] = "";
               reStrs[1] = "";
           }else if(value.length<2) {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               reStrs[1] = "";
           }else {
               if(value[0]==null) {
                   reStrs[0] = "";
               }else {
                   reStrs[0] = value[0].trim();
               }
               if(value[1]==null) {
                   reStrs[1] = "";
               }else {
                   reStrs[1] = value[1].trim();
               }
           }
        }
        return reStrs;
    }
    
    /**
     * 通过类路径获取该类的类标题
     * @author 刘虻
     * 2007-4-4上午10:04:48
     * @param classPath 类路径
     * @return 类标题
     */
    public static String getClassTitleByClassPath(String classPath) {
        return getClassTitleByClassPath(classPath,null);
    }
    
    
    /**
     * 通过类路经获取该类的类标题
     * @author 刘虻
     * 2008-1-27下午04:34:16
     * @param classPath 类路经
     * @param cl 系统类加载器
     * @return 类标题
     */
    public static String getClassTitleByClassPath(
                        String classPath,ClassLoader cl) {
        String reStr = null; //构建返回值
        Class<?> cls = null; //构建类
        try {
            if (cl==null) {
                cls = Class.forName(classPath);
            }else {
                cls = cl.loadClass(classPath);
            }
        }catch(Exception e) {}
        if (cls==null) {
            return "";
        }
        try {
            //获取变量字段
            Field field = cls.getDeclaredField("CLASS_TITLE");
            if(field!=null) {
                field.setAccessible(true);
                reStr = SString.valueOf(field.get(null));
            }
        }catch(Exception e) {}
        if (reStr==null) {
            reStr = cls.getName();
        }else {
            reStr += "["+cls.getName()+"]";
        }
        return reStr;
    }
    
    
    /**
     * 返回类实例（Bean）的变量值对照容器
     * @param obj      数据类（Bean）
     * @return            变量值对照容器
     * 2014年5月19日
     * @author 马宝刚
     */
    public static Map<String,Object> getObjectVarMap(Object obj) {
        //构建返回值
        HashMap<String,Object> reMap = new HashMap<String,Object>();
        if(obj==null) {
            return reMap;
        }
        //获取类中的字段数组
        Field[] fields = obj.getClass().getDeclaredFields();
        String fieldName; //变量名
        Class<?> fieldType; //变量类型
        for(int i=0;i<fields.length;i++) {
            try {
                fieldName = SString.valueOf(fields[i].getName());
                if("VER".equals(fieldName) || "CLASS_TITLE".equals(fieldName)) {
                    continue;
                }
                fieldType = fields[i].getType();
                if(fieldType==int.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getInt(obj)));
                }else if(fieldType==boolean.class) {
                    if(fields[i].getBoolean(obj)) {
                        reMap.put(fieldName,"1");
                    }else {
                        reMap.put(fieldName,"0");
                    }
                }else if(fieldType==double.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getDouble(obj)));
                }else if(fieldType==float.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getFloat(obj)));
                }else if(fieldType==long.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getLong(obj)));
                }else if(fieldType==short.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getShort(obj)));
                }else if(fieldType==byte.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getByte(obj)));
                }else if(fieldType==char.class) {
                    reMap.put(fieldName,String.valueOf(fields[i].getChar(obj)));
                }else if(fieldType==byte[].class) {
                    reMap.put(fieldName,new String((byte[])fields[i].get(obj)));
                }else if(fieldType==char[].class) {
                    reMap.put(fieldName,new String((char[])fields[i].get(obj)));
                }else if(fieldType==Date.class) {
                    reMap.put(fieldName,SDate.valueOf((Date)fields[i].get(obj)).getDateTime());
                }else if(fieldType==String[].class) {
                	reMap.put(fieldName,StringUtil.arr2str((String[])fields[i].get(obj)));
                }else {
                    reMap.put(fieldName,fields[i].get(obj));
                }
            }catch(Exception e) {}
        }
        return reMap;
    }
    
    /**
     * 最初异常是否为 Exception 异常
     * @author 刘虻
     * 2007-5-11下午02:06:45
     * @param e 异常
     * @return true 是
     */
    public static boolean isBaseException(Exception e) {
        
        if (e==null) {
            return false;
        }
        boolean reBoo = false;

        while(e!=null) {
            reBoo = "java.lang.Exception".equals(e.getClass().getName());
            try {
                e = (Exception)e.getCause();
            }catch(Exception ex) {}
        }
        return reBoo;
    }
    
    /**
     * 打印指定类中所有的方法信息
     * @author 刘虻
     * 2008-1-27下午03:09:47
     * @param cls 指定类
     */
    public static void printAllMethodInfo(Class<?> cls) {
        
        //获取方法信息容器
        HashMap<String,Method> infoMap = getAllMethod(cls);
        if (infoMap!=null) {
            //获取所有方法名序列
            List<String> keyList = BaseUtil.getMapKeyList(infoMap);
            for(int i=0;i<keyList.size();i++) {
                System.out.println(">>"+infoMap.get(keyList.get(i)));
            }
        }
    }
    
    /**
     * 获取指定类中的所有方法
     * @author 刘虻
     * 2008-1-27下午03:07:01
     * @param cls 指定类
     * @return 所有方法容器 key方法名  value类方法
     */
    public static HashMap<String,Method> getAllMethod(Class<?> cls) {
        //构造返回值
        HashMap<String,Method> reMap = new HashMap<String,Method>();
        getAllMethod(cls,reMap);
        return reMap;
    }
    
    
    /**
     * 获取指定类中所有的方法
     * @author 刘虻
     * 2008-1-27下午03:06:34
     * @param cls 指定类
     * @param infoMap 所有方法容器 key方法名 value方法
     */
    protected static void getAllMethod(Class<?> cls,HashMap<String,Method> infoMap) {
        
        if (cls==null || "java.lang.Object".equals(cls.getName())) {
            return;
        }
        //获取当前类的所有方法
        Method[] methods = cls.getDeclaredMethods();
        if (methods!=null) {
            for(int i=0;i<methods.length;i++) {
                if (!infoMap.containsValue(methods[i])) {
                    infoMap.put(methods[i].getName(),methods[i]);
                }
            }
        }
        //获取父类方法
        getAllMethod(cls.getSuperclass(),infoMap);
    }
    
    
    
    /**
     * 获取指定路经下所有包路经列表
     * @author 刘虻
     * 2008-1-23下午02:04:13
     * @param filesUtil 文件处理类
     * @param basePath 根路经
     * @param path 指定路经 (可以用;分割)
     * @return 包路经列表
     */
    public static ArrayList<String> getLibFilePathList(
                    IFilesUtil filesUtil,String basePath,String path) {
        
        //构建返回值
        ArrayList<String> reList = new ArrayList<String>();
        if (filesUtil==null || path==null || path.length()==0) {
            return reList;
        }
        //路径序列
        List<String> libPathList = BaseUtil.splitToList(path,";");
        if (libPathList!=null) {
            String element; //获取路径元素
            for (int i=0;i<libPathList.size();i++) {
                element = 
                    filesUtil.getAllFilePath(basePath+
                            SString.valueOf(libPathList.get(i)));
                if (element.length()==0) {
                    continue;
                }
                //准备用来判断是文件还是路径
                File elementFile = new File(element);
                if (elementFile.isDirectory()) {
                    //为路径
                    ArrayList<String> fileList = new ArrayList<String>();
                    try {
                        filesUtil.setFilePath(fileList,element,null,true,false);
                    }catch(Exception e) {
                        e.printStackTrace();
                        continue;
                    }
                    for (String filePath:fileList) {
                        if(filePath==null) {
                            continue;
                        }
                        //校验路径
                        String checkFilePath = filePath.toLowerCase();
                        if (checkFilePath.endsWith(".class") 
                                || checkFilePath.endsWith(".jar") 
                                || checkFilePath.endsWith(".zip")) {
                            reList.add(filePath);
                        }
                    }
                }else {
                    //获取文件名
                    String fileName = elementFile.getName().toLowerCase();
                    if (fileName.endsWith(".class") 
                            || fileName.endsWith(".jar") 
                            || fileName.endsWith(".zip")) {
                        reList.add(element);
                    }
                }
            }
        }
        return reList;
    }
    
    
    
      
    /**
     * 克隆对象 只针对基本类型和实现ICloneable接口的类
     * @author 刘虻
     * 2007-4-19下午12:18:04
     * @param srcObj 源对象
     * @return 克隆后对象
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Object cloneObject(
            Object srcObj) throws Exception {
        
        if (srcObj==null) {
            return null;
        }
        //构建返回值
        Object reObj = null; 
        
        if (srcObj instanceof int[]) { //int[]
            reObj = ((int[])srcObj).clone();
        }else if (srcObj instanceof long[]) { //long[]
            reObj = ((long[])srcObj).clone();
        }else if (srcObj instanceof float[]) { //float[]
            reObj = ((float[])srcObj).clone();
        }else if (srcObj instanceof double[]) { //double[]
            reObj = ((double[])srcObj).clone();
        }else if (srcObj instanceof char[]) { //char[]
            reObj = ((char[])srcObj).clone();
        }else if (srcObj instanceof byte[]) { //byte[]
            reObj = ((byte[])srcObj).clone();
        }else if (srcObj instanceof boolean[]) { //booelan[]
            reObj = ((boolean[])srcObj).clone();
        }else if (srcObj instanceof String[]) { //String[]
            reObj = ((String[])srcObj).clone();
        }else if (srcObj instanceof Integer[]) { //Integer[]
            reObj = ((Integer[])srcObj).clone();
        }else if (srcObj instanceof Long[]) { //Long[]
            reObj = ((Long[])srcObj).clone();
        }else if (srcObj instanceof Float[]) { //Float[]
            reObj = ((Float[])srcObj).clone();
        }else if (srcObj instanceof Double[]) { //Double[]
            reObj = ((Double[])srcObj).clone();
        }else if (srcObj instanceof Byte[]) { //Byte[]
            reObj = ((Byte[])srcObj).clone();
        }else if (srcObj instanceof Boolean[]) { //Boolean[]
            reObj = ((Boolean[])srcObj).clone();
        }else if (srcObj instanceof ArrayList[]) { //ArrayList[]
            reObj = new ArrayList[((ArrayList[])srcObj).length];
            for (int i=0;i<((ArrayList[])reObj).length;i++){
                ((ArrayList[])reObj)[i] = 
                    (ArrayList)cloneObject(((ArrayList[])srcObj)[i]);
            }
        }else if (srcObj instanceof HashMap[]) { //HashMap[]
            reObj = new HashMap[((HashMap[])srcObj).length];
            for (int i=0;i<((HashMap[])reObj).length;i++){
                ((HashMap[])reObj)[i] = 
                    (HashMap)cloneObject(((HashMap[])srcObj)[i]);
            }
        }else if (srcObj instanceof Vector[]) { //Vector[]
            reObj = new Vector[((Vector[])srcObj).length];
            for (int i=0;i<((Vector[])reObj).length;i++){
                ((Vector[])reObj)[i] = 
                    (Vector)cloneObject(((Vector[])srcObj)[i]);
            }
        }else if (srcObj instanceof Properties[]) { //Properties[]
            reObj = new Properties[((Properties[])srcObj).length];
            for (int i=0;i<((Properties[])reObj).length;i++){
                ((Properties[])reObj)[i] = 
                    (Properties)cloneObject(((Properties[])srcObj)[i]);
            }
        }else if (srcObj instanceof Hashtable[]) { //Hashtable[]
            reObj = new Hashtable[((Hashtable[])srcObj).length];
            for (int i=0;i<((Hashtable[])reObj).length;i++){
                ((Hashtable[])reObj)[i] = 
                    (Hashtable)cloneObject(((Hashtable[])srcObj)[i]);
            }
        }else if (srcObj instanceof Integer) { //Integer
            reObj = srcObj;
        }else if (srcObj instanceof Long) { //Long
            reObj = srcObj;
        }else if (srcObj instanceof Boolean) { //Boolean
            reObj = srcObj;
        }else if (srcObj instanceof Float) { //Float
            reObj = srcObj;
        }else if (srcObj instanceof Double) { //Double
            reObj = srcObj;
        }else if (srcObj instanceof Byte) { //Byte
            reObj = srcObj;
        }else if (srcObj instanceof String) { //String
            reObj = srcObj;
        }else if (srcObj instanceof HashMap) {
            
            reObj = new HashMap();
            Set keySet = ((HashMap)srcObj).entrySet();
            Object key = null; //主键
            Iterator keyIterator = keySet.iterator();
            while (keyIterator.hasNext()) {
                Map.Entry mapKey = (Map.Entry) keyIterator.next();
                key = mapKey.getKey();
                ((HashMap)reObj).put(
                        cloneObject(key)
                        ,cloneObject(((HashMap)srcObj).get(key)));
            }
            
        }else if (srcObj instanceof Hashtable) {
            
            reObj = new Hashtable();
            Set keySet = ((Hashtable)srcObj).entrySet();
            Object key = null; //主键
            Iterator keyIterator = keySet.iterator();
            while (keyIterator.hasNext()) {
                Map.Entry mapKey = (Map.Entry) keyIterator.next();
                key = mapKey.getKey();
                ((Hashtable)reObj).put(
                        cloneObject(key)
                        ,cloneObject(((Hashtable)srcObj).get(key)));
            }
            
        }else if (srcObj instanceof ArrayList) {
            
            reObj = new ArrayList();
            for (int i=0;i<((ArrayList)srcObj).size();i++) {
                ((ArrayList)reObj).add(cloneObject(((ArrayList)srcObj).get(i)));
            }
            
        }else if (srcObj instanceof Vector) {
            
            reObj = new Vector();
            for (int i=0;i<((Vector)srcObj).size();i++) {
                ((Vector)reObj).add(cloneObject(((Vector)srcObj).get(i)));
            }
            
        }else if (srcObj instanceof Properties) {
            
            reObj = new Properties();
            Set keySet = ((Properties)srcObj).entrySet();
            String key = null; //主键
            Iterator keyIterator = keySet.iterator();
            while (keyIterator.hasNext()) {
                Map.Entry mapKey = (Map.Entry) keyIterator.next();
                key = SString.valueOf(mapKey.getKey());
                ((Properties)reObj).setProperty(
                        key
                        ,SString.valueOf(((Properties)srcObj).get(key)));
            }
        }else if (srcObj instanceof ICloneable[]) {
            
            reObj = Array.newInstance(
                    ((Object[])srcObj)[0].getClass()
                    ,((Object[])srcObj).length);
            for (int i=0;i<((Object[])srcObj).length;i++) {
                reObj = ((ICloneable)((Object[])srcObj)[i]).clone();
            }
            
        }else if (srcObj instanceof ICloneable) {
            reObj = ((ICloneable)srcObj).clone();
        }else {
            reObj = srcObj ;
        }
        return reObj;
    }
    
    
    /**
     * 通过指定类型，内容字符串，返回设置好值的类实例
     * 
     * 字符串中，数组或序列元素用：分割   map中主键与值用=分割
     * 
     * 传入的类型只限定于 String int long float double boolean List ArrayList Vector Map Hashtable HashMap
     * 
     * 刘虻
     * 2012-6-24 下午12:36:12
     * @param cls               指定类型对象
     * @param valueInfo   需要设置的值
     * @return 设置好值的类实例
     * @throws Exception 异常
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Object getObjectByClass(Class<?> cls,String valueInfo) throws Exception {
        //处理基本类型
        if(cls == String.class) {
            return valueInfo;
        }else if(cls == int.class) {
            return SInteger.integerOf(valueInfo);
        }else if(cls == long.class) {
            return SLong.longOf(valueInfo);
        }else if(cls == float.class) {
            return SDouble.doubleOf(valueInfo);
        }else if(cls == double.class) {
            return SDouble.doubleOf(valueInfo);
        }else if(cls == boolean.class) {
            return SBoolean.booleanOf(valueInfo);
        }
        Object reObj = null; //构建返回值
        List eleList = BaseUtil.splitToList(valueInfo,":"); //元素信息
        if(cls==List.class || cls==Vector.class || cls==ArrayList.class) {
            if(cls==Vector.class) {
                reObj = new Vector();
            }else {
                reObj = new ArrayList();
            }
            for(int i=0;i<eleList.size();i++) {
                ((List)reObj).add(eleList.get(i));
            }
        }else if(cls==Map.class || cls==Hashtable.class || cls==HashMap.class) {
            if(cls==Hashtable.class) {
                reObj = new Hashtable();
            }else {
                reObj = new HashMap();
            }
            String ele; //元素
            for(int i=0;i<eleList.size();i++) {
                ele = SString.valueOf(eleList.get(i));
                int point = ele.indexOf("="); //分割点
                if(point>0) {
                    ((Map)reObj).put(ele.substring(0,point),ele.substring(point+1));
                }
            }
        }
        return reObj;
    }
    
    /**
     * 判断指定类型中是否实现了指定接口 （递归函数）
     * @param cls 指定类型
     * @param interfaceCls 指定接口
     * @return true实现了
     * 2014年6月22日
     * @author 马宝刚
     */
    public static boolean implementsClass(Class<?> cls,Class<?> interfaceCls) {
        if(cls==null || cls==Object.class || interfaceCls==null) {
            return false;
        }
        Class<?>[] classes = cls.getInterfaces(); //获取该类型的接口类型数组
        for(Class<?> iCls:classes) {
            if(iCls==interfaceCls) {
                return true;
            }
            if(iCls.getName().equals(interfaceCls.getName())) {
            	return true;
            }
        }
        return implementsClass(cls.getSuperclass(),interfaceCls);
    }
    
    
    /**
     * 判断指定类型中是否实现了指定接口（不是递归函数）
     * @param cls 指定类型
     * @param interfaceCls 指定接口
     * @return true实现了
     * 2014年6月22日
     * @author 马宝刚
     */
    public static boolean implementsClass(ClassFile cf,Class<?> cls) {
		if(cls==null) {
			return false;
		}
		//实现的接口类名数组
		String[] interfaceClasses = null;
		try {
			interfaceClasses = cf.getInterfaces();
		}catch(Exception e) {
			e.printStackTrace();
		}
		if(interfaceClasses==null || interfaceClasses.length<1) {
			return false;
		}
		String className = cls.getName(); //获取接口类名
		for(int i=0;i<interfaceClasses.length;i++) {
			if(className.equals(interfaceClasses[i])) {
				return true;
			}
		}
		return false;
    }
    
    
    /**
     * 获取声明的变量，如果没有，从父类中获取（递归函数）
     * @param fieldName 变量名
     * @param cls 指定类
     * @return 变量对象
     * 2016年3月17日
     * @author 马宝刚
     */
    public static Field getDeclaredField(String fieldName,Class<?> cls) {
        if(fieldName==null || cls==null || cls==Object.class) {
            return null;
        }
        //获取该类的全部变量
        Field[] fields = cls.getDeclaredFields();
        if(fields!=null) {
            for(Field ele:fields) {
                if(fieldName.equals(ele.getName())) {
                    return ele;
                }
            }
        }
        //从父类中获取
        return getDeclaredField(fieldName,cls.getSuperclass());
    }
    
    
    /**
     * 通过类对象，获取该类所在的文件路径
     * @param cls 类对象
     * @return 类文件所在路径
     * 2016年3月3日
     * @author 马宝刚
     */
    public static String getClassFilePathStr(Class<?> cls) {
        if(cls==null) {
            return "";
        }
        URL pathUrl = null; //构建返回值
        if (cls.getClass().getProtectionDomain()!=null 
                && cls.getClass().getProtectionDomain().getCodeSource()!=null) {
            pathUrl = cls.getClass().getProtectionDomain().getCodeSource().getLocation();
        }
        if(pathUrl==null) {
            return "";
        }
        //获取类所在的路径
        String path = pathUrl.toString();
        if(path.toLowerCase().endsWith(".jar")) {
            //类在压缩包中
            return path+"!/"+cls.getName().replace(".","/")+".class";
        }
        //类在文件夹中
        return path+"/" +cls.getName().replace(".","/")+".class";
    }
    
    
    /**
     * 测试入口
     * @author 刘虻
     * 2007-3-13下午12:39:14
     * @param args 导入参数
     */
    public static void main(String[] args) {

        try {
            System.out.println(getClassPathByFilePath("D:/javacode/aengine/root/WEB-INF/appcls/com/aresoft/sf/action/fundweb/DemoUserInfoAction.class",null));
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断是否存在该方法
     * @param cls 指定类
     * @param methodName 方法名
     * @return 是否存在该方法
     * 2017年3月30日
     * @author MBG
     */
    public static boolean hasMethod(Class<?> cls,String methodName) {
    	if(cls==null || methodName==null || methodName.length()<1) {
    		return false;
    	}
    	Method[] methods = cls.getMethods();
    	if(methods==null) {
            return false;
        }
    	for(int i=0;i<methods.length;i++) {
    		if(methodName.equals(methods[i].getName())) {
    			return true;
    		}
    	}
    	return false;
    }
    
    
    //#region exists(className) 判断指定类是否存在
    /**
     * 判断指定类是否存在
     * @param className 完整类名（包含包名）
     * @return          是否存在
     */
	public static boolean exists(String className) {
		try {
			// 尝试加载类
			Class<?> cls = Class.forName(className,true, ClassUtil.class.getClassLoader());
			if(cls!=null) {
				return true;
			}
		}catch(Exception e) {}
		return false;
	}
	//#endregion
}







